'use client';

import type { IDifference, ISectionClient } from '@/interfaces';
import { clientQueryAllSection, createPostTemplate } from '@/services/api';
import { useMutation, useQuery } from '@tanstack/react-query';
import {
  type ChangeEvent,
  type FormEvent,
  useEffect,
  useRef,
  useState,
} from 'react';
import useToast from '@/hooks/useToast';
import diff from 'microdiff';
import { getDiffData, isNum } from '@/lib/tool';
import Box from '@/app/[locale]/admin/common/box';
import Spinner from '@/app/[locale]/component/spinner/spinner';
import { useRouter } from 'next/navigation';
import Alert from '@/app/[locale]/alert/alert';
import AlertLoad from '@/app/[locale]/alert/load';
import { getEditorContentHtml, setEditorContentHtml } from '@/lib/editor';
import {
  handleEditorBeforeunload,
  handleEditorSave,
  handleEditorStatusChanges,
} from '@/lib/editor/handle';
import dynamic from 'next/dynamic';
import EditorSuspense from '@/app/[locale]/posts/[id]/edit/editor/load';
import Nodata from '@/app/[locale]/common/nodata/nodata';
import type { PrefixedTTranslatedFields } from '@/lib/dictionaries';

const DynamicEditor: any = dynamic(
  () => import('../../../../posts/[id]/edit/editor/editor'),
  {
    loading: () => <EditorSuspense />,
    ssr: false,
  },
);

export default function CreatePostTemplateGroupAdminPage({
  source,
  translatedFields,
}: {
  source?: any;
  translatedFields: PrefixedTTranslatedFields<'postTemplateAdminPage'>;
}) {
  const [form, setForm] = useState({
    name: '',
    content: '',
    sectionId: '',
  });
  const [differenceData, setDifferenceData] = useState<IDifference[]>([]);
  const { show } = useToast();
  const router = useRouter();
  const [isDisabledSave, setIsDisabledSave] = useState(true);
  const editorRef = useRef<any>();
  const [isActive, setIsActive] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const isDirty = useRef(false);
  const isLoadingSave = useRef(false);
  const [isReady, setIsReady] = useState(false);

  const clientQueryAllSectionQuery = useQuery(
    ['/forum', '/sections', '/client'],
    async () => {
      return (await clientQueryAllSection()) as ISectionClient[];
    },
  );

  const createPostTemplateMutation = useMutation(createPostTemplate);

  useEffect(() => {
    const diffData = diff(
      {
        name: '',
      },
      form,
    );
    setDifferenceData(diffData);
    setIsDisabledSave(diffData.length === 0);
  }, [form]);
  useEffect(() => {
    const selector = document.querySelector('.yw-navbar-layout');
    if (selector) {
      selector.classList.remove('sticky-top');
    }

    return () => {
      if (selector) {
        selector.classList.add('sticky-top');
      }
    };
  }, []);

  async function onSubmit(e: FormEvent<HTMLFormElement>) {
    e.preventDefault();
    e.stopPropagation();
    await onClickSave();
  }

  function getContent(data?: any) {
    return getEditorContentHtml(editorRef.current, data);
  }

  async function onClickSave() {
    const editor = editorRef.current;
    if (!editor) {
      show({
        type: 'DANGER',
        message: translatedFields.tip.editorDoesNotExist,
      });
      return;
    }

    await handleEditorSave({
      editor,
      isDirty,
      setIsActive,
      setIsSaving,
      callback: onClickSaveCore,
    });
  }

  async function onClickSaveCore({
    data,
    reset,
  }: {
    data: string;
    reset: () => void;
  }) {
    try {
      isLoadingSave.current = true;

      checkForm();
      const _data = getDiffData(differenceData) as any;

      await createPostTemplateMutation.mutateAsync({
        data: {
          ..._data,
          content: getContent(data),
        },
      });

      show({
        type: 'SUCCESS',
        message: translatedFields.operate.saveCompleted,
      });

      setTimeout(() => {
        show({
          type: 'PRIMARY',
          message: translatedFields.operate.refreshPending,
        });
      }, 1000);

      setTimeout(() => {
        router.back();
      }, 1500);
    } catch (e) {
      createPostTemplateMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    } finally {
      isLoadingSave.current = false;
      reset();
    }
  }

  function checkForm() {
    const { name, content, sectionId } = form;

    if (!name) {
      throw translatedFields.tip.required;
    }

    if (!sectionId || !isNum(sectionId)) {
      throw translatedFields.tip.sectionIdRequired;
    }

    if (!getContent()) {
      throw translatedFields.tip.contentRequired;
    }
  }

  function onChange(e: ChangeEvent<HTMLInputElement | HTMLSelectElement>) {
    const name = e.target.name;
    const value = e.target.value;
    setForm({ ...form, [name]: value });
  }

  function onReady({ editor }: { editor: any }) {
    handleEditorStatusChanges({
      editor,
      isDirty,
      setIsActive,
      setIsSaving,
    });
    handleEditorBeforeunload({ editor });
    setEditorContentHtml(editor, form.content);
    editorRef.current = editor;
    setIsReady(true);
  }

  return (
    <Box>
      <div className="card">
        <div className="card-body">
          <form onSubmit={onSubmit} className="vstack gap-4">
            <div>
              <label className="form-label">
                {translatedFields.properties.name}
              </label>
              <input
                type="text"
                name="name"
                value={form.name}
                onChange={onChange}
                className="form-control"
                aria-describedby="name"
                placeholder={translatedFields.tip.namePlaceholder}
              />
            </div>

            <div>
              <label className="form-label">
                {translatedFields.properties.section}
              </label>
              {clientQueryAllSectionQuery.data &&
                clientQueryAllSectionQuery.data.length > 0 && (
                  <select
                    name="sectionId"
                    value={form.sectionId}
                    onChange={onChange}
                    className="form-select"
                    placeholder={translatedFields.tip.sectionPlaceholder}
                  >
                    <option disabled value="">
                      {translatedFields.tip.sectionPlaceholder}
                    </option>
                    {clientQueryAllSectionQuery.data.map((item) => {
                      return (
                        <option key={item.id} value={item.id}>
                          {item.name}
                        </option>
                      );
                    })}
                  </select>
                )}

              {clientQueryAllSectionQuery.data &&
                clientQueryAllSectionQuery.data.length === 0 && <Nodata />}

              {clientQueryAllSectionQuery.isError && (
                <Alert
                  message={clientQueryAllSectionQuery.error}
                  type="error"
                />
              )}

              {clientQueryAllSectionQuery.isLoading && <AlertLoad />}
            </div>

            {form.sectionId && (
              <div>
                <label className="form-label">
                  {translatedFields.properties.content}
                </label>
                <DynamicEditor
                  id={form.sectionId}
                  type="postTemplate"
                  onReadyCallback={onReady}
                />
              </div>
            )}

            <button
              type="submit"
              disabled={createPostTemplateMutation.isLoading || isDisabledSave}
              className="btn btn-primary col col-lg-2 mt-4"
            >
              {createPostTemplateMutation.isLoading && (
                <Spinner classs="me-2" />
              )}
              {translatedFields.operate.save}
            </button>
          </form>
        </div>
      </div>
    </Box>
  );
}
